import os
from utils.Logger import LogPrint
import base64
import pdf2image
import time
from enum import Enum
from PIL import Image
from datetime import datetime
from PyQt6.QtCore import QRunnable,QThread, QObject,pyqtSlot,pyqtSignal
import io

class ImageFmt(Enum):
    JPG = 0
    PNG = 1
    PPM = 2

def pdf2Images(pdfPath,quality=0,savePath=None,fmt=ImageFmt.JPG,pageStartEndList=None):
    LogPrint.debug('pageStartEndList',pageStartEndList)
    result=[]
    if pageStartEndList:
        for pageNo in pageStartEndList:
            startPage=pageNo[0]
            endPage=pageNo[1]
            images,tempFileDir=pdfConvertToPreImage(pdfPath,quality,savePath,fmt,True,startPage,endPage)
            directory, filename = os.path.split(tempFileDir)
            result.append(filename)
    else :
        images,tempFileDir=pdfConvertToPreImage(pdfPath,quality,savePath,fmt,True)
        directory, filename = os.path.split(tempFileDir)
        result.append(filename)
    
    return result


#quality--质量，0--标清，1--高清
#fmt---文件格式，png、jpg、ppm
#export---导出状态
def pdfConvertToPreImage(pdfPath,quality=0,savePath=None,fmt=ImageFmt.JPG,
                         export=False,startPage=1,endPage=None):

    LogPrint.info('pdfPath ',pdfPath,quality,savePath,fmt)
    images=None
    tempFileDir=None
    if pdfPath is None or pdfPath=='' :
        LogPrint.info('pdfConvertToPreImage pdfPath is None')
        return 
    try :
        # 使用os.path.split()分割路径和文件名
        dirname, filename = os.path.split(pdfPath)
        tempRootPath=getTempImageRootPath()
        #LogPrint.info(dirname,filename)
        strFiles=str(filename).split('.')
        if strFiles and len(strFiles)>1:
            strName=strFiles[0]
        else :
            strName = base64.b64encode(pdfPath.encode('utf-8'))
        outputPath=tempRootPath+strName

        tempFileDir=outputPath
        ###
        signStatus=False
        if export==False:
            signStatus,lastMillis=getSignFileStatus(outputPath)
        if signStatus == False:

            # 检查目录是否存在
            if not os.path.exists(outputPath):
                # 如果目录不存在，则创建目录
                os.makedirs(outputPath)
            #设置参数
            paramQualit=50
            if quality==1:
                paramQualit=200
            paramPath=outputPath
            if savePath:
                paramPath=savePath+'/'+strName+'_'+getCurrentDate()
                tempFileDir=paramPath
            paramFmt='jpg'
            if fmt==ImageFmt.PNG:
                paramFmt='png'
            elif fmt==ImageFmt.PPM:
                paramFmt='ppm'
            # 检查目录是否存在
            if not os.path.exists(paramPath):
                # 如果目录不存在，则创建目录
                os.makedirs(paramPath)
            LogPrint.info('convert_from_path',pdfPath,paramQualit,paramPath,paramFmt)
            if not str(startPage).isdigit():
                startPage=1
            currMillis=None
            if export==False:
                currMillis=writeSignFile(outputPath)
            paramOutputFile=strName

            if currMillis:
                paramOutputFile=strName+'_'+str(currMillis)
            if endPage and str(endPage).isdigit():
                images = pdf2image.convert_from_path(pdfPath,dpi=paramQualit,
                                                     first_page=startPage,
                                                     last_page=endPage,
                                                     thread_count=5,
                                                     output_folder=paramPath,
                                                     fmt=paramFmt,
                                                     output_file=paramOutputFile)
            else :
                images = pdf2image.convert_from_path(pdfPath,dpi=paramQualit,
                                                     first_page=startPage,
                                                     thread_count=5,
                                                     output_folder=paramPath,
                                                     fmt=paramFmt,
                                                     output_file=paramOutputFile)
            

    except Exception as e:
        LogPrint.error('pdfToImage 读取pdf文件失败',e)
    return images,tempFileDir

def writeSignFile(outputPath):
    #转换成功后，写入标记，便于下次直接使用
    currMillis = int(round(time.time()))
    with open(outputPath+'/sign.txt', 'w') as file:
        file.write(str(currMillis))
        return currMillis

def getSignFileStatus(outputPath) :
    if os.path.exists(outputPath+'/sign.txt')==False:
        return False,None
    file=open(outputPath+'/sign.txt', 'r')
    if file:
        text=file.read()
        LogPrint.info('getSignFile',text)
        currMillis = int(round(time.time()))
        if currMillis - int(text) < 30*60:
            #判断image文件是否存在
            fileList = os.listdir(outputPath)
            if fileList and len(fileList) > 1:
                for file in fileList:
                    if text in file:
                        return True,text
        if isinstance(file, io.IOBase):
            file.close()
        os.remove(outputPath+'/sign.txt')
    return False,None

#目录下读取图片文件列表
def getPdfImageList(filePath,imageNoList=None):
    if filePath:
        if not os.path.isfile(filePath+'/sign.txt'):
            fileList = os.listdir(filePath)
            return fileList
        #获取标记字符串
        file=open(filePath+'/sign.txt', 'r')
        if file:
            text=file.read()
            fileList = os.listdir(filePath)
            if fileList and len(fileList) > 0:
                fileListContainSign=[]
                for fileName in fileList:
                    if text in fileName:
                        fileListContainSign.append(fileName)
                if imageNoList and len(fileListContainSign) > 0:
                    index =1
                    fileListTemp=[]
                    for fileName in fileListContainSign:
                        if index in imageNoList:
                            fileListTemp.append(fileName)
                            index+=1
                    return fileListTemp
                return fileListContainSign
    
    return []

def combinePdfImages(pdfPathList,quality=0,savePath=None,fmt=ImageFmt.JPG,imageNoList=None,pageStartEndList=None):
    #先导出单张图片
    tempRootPath=getTempImageRootPath()
    tempSavePath=tempRootPath+'export_tmp_dir_'+str(getCurrentDate())
    exportFileName=''
    for pdfPath in pdfPathList:
        dirname, filename = os.path.split(pdfPath)
        pdf2Images(pdfPath,quality,tempSavePath,fmt,pageStartEndList)
        exportFileName+=str(filename).split('.')[0]
        exportFileName+='_'

    filename=combineImages2(tempSavePath,savePath=savePath,imageNoList=imageNoList,fmt=fmt,exportFileName=exportFileName)
    return filename

#合成图片
def combineImages2(imageParentPath, savePath, imageNoList=None,fmt=ImageFmt.JPG,exportFileName=None,direction='vertical'):
    images = []
    LogPrint.debug(imageParentPath,savePath) 
    imagePathList = os.listdir(imageParentPath)
    for imagePath in imagePathList:

        fileList=getPdfImageList(imageParentPath+'\\'+imagePath,imageNoList)

        LogPrint.debug(imagePath,fileList) 
        for filePath in fileList:
            images.append(Image.open(imageParentPath+'\\'+imagePath+'/'+filePath))
    
    # 创建一个新的空白图片，宽度和高度根据拼接方向计算
    if direction == 'vertical':
        result = Image.new('RGB', (images[0].width, sum(image.height for image in images)))
        offset = 0
    else:
        result = Image.new('RGB', (sum(image.width for image in images), images[0].height))
        offset = 0
 
    # 将每张图片逐一粘贴到结果图片上
    for image in images:
        if direction == 'vertical':
            result.paste(image, (0, offset))
            offset += image.height
        else:
            result.paste(image, (offset, 0))
            offset += image.width
    postfix='.jpg'
    if fmt==ImageFmt.PNG:
        postfix='.png'
    fileName='result_'+getCurrentDate()+postfix
    if exportFileName:
        fileName=exportFileName+getCurrentDate()+postfix
    result.save(savePath+'\\'+fileName)

    return fileName


#合成图片
def combineImages(imagePathList, savePath, imageNoList=None,fmt=ImageFmt.JPG,exportFileName=None,direction='vertical'):
    images = []
    LogPrint.debug(imagePathList,savePath) 
    for imagePath in imagePathList:
        #获取临时存储目录
        dirname, filename = os.path.split(imagePath)
        #LogPrint.info(dirname,filename)
        strFiles=str(filename).split('.')
        if strFiles and len(strFiles)>1:
            strName=strFiles[0]
        else :
            strName = base64.b64encode(imagePath.encode('utf-8'))
        tempRootPath=getTempImageRootPath()
        tempImagePath=tempRootPath+str(strName)

        fileList=getPdfImageList(tempImagePath,imageNoList)

        LogPrint.debug(tempImagePath,fileList) 
        for filePath in fileList:
            images.append(Image.open(tempImagePath+'/'+filePath))
    
    # 创建一个新的空白图片，宽度和高度根据拼接方向计算
    if direction == 'vertical':
        result = Image.new('RGB', (images[0].width, sum(image.height for image in images)))
        offset = 0
    else:
        result = Image.new('RGB', (sum(image.width for image in images), images[0].height))
        offset = 0
 
    # 将每张图片逐一粘贴到结果图片上
    for image in images:
        if direction == 'vertical':
            result.paste(image, (0, offset))
            offset += image.height
        else:
            result.paste(image, (offset, 0))
            offset += image.width
    postfix='.jpg'
    if fmt==ImageFmt.PNG:
        postfix='.png'
    fileName='result_'+getCurrentDate()+postfix
    if exportFileName:
        fileName=exportFileName+getCurrentDate()+postfix
    result.save(savePath+'\\'+fileName)

#获取临时文件存储目录
def getTempImageRootPath():
    # 获取当前用户的AppData\Local目录
    localPath = os.path.join(os.environ['LOCALAPPDATA'], '')
    tempPath=localPath+'Pdf2Image\\'
    return tempPath

#获取当前年月日时分秒--作为文件名称中一部分
def getCurrentDate():

    # 获取当前时间
    now = datetime.now()
    
    # 格式化当前时间，例如：2023-03-25_14:30:00
    formattedTime = now.strftime('%Y-%m-%d_%H-%M-%S')
    return formattedTime


# # 定义一个继承自 QObject 的子类来作为我们的工作器 (worker)
# class WorkerSignals(QObject):
#     finished = pyqtSignal(object)
 
# class Worker(QRunnable):
#     def __init__(self, fn, *args, **kwargs):
#         super(Worker, self).__init__()
#         self.fn = fn
#         self.args = args
#         self.kwargs = kwargs
#         self.signals = WorkerSignals()
        
#         # 当任务完成时，发出信号
#         self.signals.finished.connect(self.deleteLater)
 
#     @pyqtSlot()
#     def run(self):
#         # 运行任务
#         result = self.fn(*self.args, **self.kwargs)
#         self.signals.finished.emit(result)

#     def deleteLater(self):

#         LogPrint.debug('deleteLater')


# #在子进程中执行加载pdf过程
# def startPdfToPreImageSubprocessTask(pdfPath,quality=0,savePath=None,fmt=ImageFmt.JPG,
#                          export=False,startPage=1,endPage=None):
#         # 创建一个 QThread 实例，并将 Worker 实例移到这个线程中
#         thread = QThread()
#         worker = Worker(pdfConvertToPreImage, pdfPath,quality,savePath,fmt,
#                          export,startPage,endPage)
#         #worker.moveToThread(thread)
 
#         # 连接任务完成的信号槽
#         worker.signals.finished.connect(handleResults)
 
#         # 当线程开始时，启动任务
#         thread.started.connect(worker.run)
 
#         # 当线程结束时，删除线程对象
#         thread.finished.connect(thread.deleteLater)
 
#         # 启动线程
#         thread.start()
        
# @pyqtSlot(object)
# def handleResults( result):
#         # 处理任务完成后的结果
#         print(result)